using System;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Configuration;
using System.Collections;
using System.Collections.Specialized;
using System.Data;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using VB = Microsoft.VisualBasic;
//using eX = eXpressServer;
using Dimok;
using Interop.PrepTools;

namespace Dimok.Documents{

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>	Utilities. </summary>
	///
	/// <remarks>	Dimon, 12/21/2010. </remarks>
	////////////////////////////////////////////////////////////////////////////////////////////////////

	public class Utilities : MarshalByRefObject{

		#region Activates
		/*
		public static eX.ConversionObjectClass ActivateConversionObject(){
			//return new eXpressServer.ConversionObjectClass();
			eX.ConversionObjectClass ex = null;
			try{ex = (eX.ConversionObjectClass)VB.Interaction.GetObject("","eXpressServer.ConversionObject");
			}catch(COMException exc){if( exc.ErrorCode != -2147221021 )throw;}
			if( ex == null )ex = new eXpressServer.ConversionObjectClass();
			return ex;
		}
		public static eX.DestinationClass ActivateDestinationObject(){
			return new eX.DestinationClass();
			//eX.DestinationClass dest = null;
			//try{dest = (eX.DestinationClass)Marshal.GetActiveObject("eXpressServer.Destination");
			//}catch(COMException exc){if( exc.ErrorCode != -2147221021 )throw;}
			//if( dest == null )dest = new eXpressServer.DestinationClass();
			//return dest;
		}
		 * */
		#endregion

		#region CombineWordToPDF
		/*
		public static byte[] CombineWordToPDF(byte[][] files,string connection,string sql){
			return FileManager.GetBytesFromFile(CombineWordToPDF(files,".pdf",connection,sql),true);
		}
		public static string CombineWordToPDF(byte[][] files,string fileOut,string connection,string sql){
			ArrayList alFileNames = new ArrayList();
			foreach( byte[] file in files )
				alFileNames.Add(FileManager.GetFileFromBytes(file,".doc",true));
			try{
				return CombineWordToPDF(alFileNames,fileOut,connection,sql);
			}finally{
				FileManager.DeleteFiles(alFileNames);
			}
		}
		public static string CombineWordToPDF(ArrayList fileNames,string fileOut,string connection,string sql){
			return CombineWordToPDF((string[])fileNames.ToArray(typeof(string)),fileOut,connection,sql);
		}
		public static string CombineWordToPDF(string[] fileNames,string fileOut,string connection,string sql){
			fileNames = new Word().FillForm(fileNames,connection,sql);
			try{
				return FileManager.GetFileFromBytes(PDF.AnyToPDF(fileNames),fileOut);
			}finally{
				FileManager.DeleteFiles(fileNames);
			}
		}
		*/
		#endregion
		
		#region CombineToPDF
		/*
		public static byte[] CombineToPDF(byte[][] files){
			ArrayList alFileNames = new ArrayList();
			foreach( byte[] file in files )
				alFileNames.Add(FileManager.GetFileFromBytes(file,".doc",true));
			try{
				return FileManager.GetBytesFromFile(CombineToPDF((string[])alFileNames.ToArray(typeof(string)),".pdf"),true);
			}finally{
				FileManager.DeleteFiles(alFileNames);
			}
		}
		public static string CombineToPDF(ArrayList fileNames,string fileOut){
			return CombineToPDF((string[])fileNames.ToArray(typeof(string)),fileOut);
		}
		*/
		/*
		[MethodImplAttribute(MethodImplOptions.Synchronized)]
		public static string CombineToPDF(string[] fileNames,string fileOut){
			if( !Path.IsPathRooted(fileOut) )fileOut = Path.Combine(Path.GetDirectoryName(fileNames[0]),fileOut);
			fileOut = FileManager.BuildFullFileName(fileOut,true);
			eX.ConversionObjectClass ex = ActivateConversionObject();
			try{
				eX.DestinationClass exDest = new eXpressServer.DestinationClass();
				object m = Missing.Value;
				eX.DocInputs docsIn = ex.get_DocInputs();
				eX.DocOutputs docsOut = ex.get_DocOutputs();
				foreach( string fileName in fileNames )
					docsIn.Add(Path.GetFileName(fileName),Path.GetDirectoryName(fileName),"",0,"","","");
				docsOut.Add(AdUtil.eXpOutputType.aeOutputTypePDF,Path.GetFileName(fileOut),Path.GetDirectoryName(fileOut),exDest,"");
				int ret = 0;
				DateTime time = DateTime.Now;
				while( DateTime.Now.Subtract(time).TotalSeconds <= 5 ){
					Thread.Sleep(1000);
					if( (ret = ex.Convert()) == 0 )break;
				}
				if( ret != 0 )throw new Exception(Environment.NewLine+"Last Error:"+ex.ErrorMessage+Environment.NewLine+"Files In:"+string.Join(",",fileNames)+Environment.NewLine+"File Out:"+fileOut);
				return fileOut;
			}finally{
				ex.Reset();
				//Marshal.ReleaseComObject(ex);
			}
		}
		*/
		#endregion
		/// <summary>
		/// Gets byte[] file of document (application, contract, etc.) and returns StringDictionary containing fieldName:token pairs.
		/// </summary>
		public static StringDictionary AnalyseForm(Matrix mx,DataRowCollection docMap){
			return AnalyseForm(mx,docMap,false);
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	
		/// Gets byte[] file of document (application, contract, etc.) and returns StringDictionary
		/// containing fieldName:token pairs. 
		/// </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <exception cref="NoAnchorFoundException">	Thrown when noanchorfound. </exception>
		///
		/// <param name="mx">												The mx. </param>
		/// <param name="docMap">										The document map. </param>
		/// <param name="returnAfterFirstSuccess">	true if the return after first operation was a success,
		/// 																				false if it failed. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static StringDictionary AnalyseForm(Matrix mx,DataRowCollection docMap,bool returnAfterFirstSuccess){
			Token ttAnchor = mx.FindPhrase(docMap[0]["Key"]+"",true);
			if( ttAnchor == null )throw new NoAnchorFoundException("form");
			StringDictionary sd = new StringDictionary();
			for( int i=1; i < docMap.Count; i++ ){
				string val = docMap[i]["Coords"]+"";
				int x = int.Parse(val.Split(',')[0]);
				int y = int.Parse(val.Split(',')[1]);
				Token token = mx.FindLocation((int)ttAnchor.X+x,(int)ttAnchor.Y+y,GetRangeX(docMap,i),GetRangeY(docMap,i));
				string str = token == null ? "" : token.Text;
				sd.Add(docMap[i]["Key"]+"",str);
				if( returnAfterFirstSuccess && token != null )break;
			}
			return sd;
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets a range x coordinate. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="rows">			The rows. </param>
		/// <param name="rowIndex">	Zero-based index of the row. </param>
		///
		/// <returns>	The range x coordinate. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		private static RangeX GetRangeX(DataRowCollection rows,int rowIndex) {
			string val = rows[rowIndex]["RangeX"]+"";
			if( val != "" )return new RangeX(val);
			return new RangeX(rows[0]["RangeX"]+"");
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets a range y coordinate. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="rows">			The rows. </param>
		/// <param name="rowIndex">	Zero-based index of the row. </param>
		///
		/// <returns>	The range y coordinate. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		private static RangeY GetRangeY(DataRowCollection rows,int rowIndex) {
			string val = rows[rowIndex]["RangeY"]+"";
			if( val != "" )return new RangeY(val);
			return new RangeY(rows[0]["RangeY"]+"");
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets a glossary. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="pdfFile">	The pdf file. </param>
		///
		/// <returns>	The glossary. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static string GetGlossary(string pdfFile){return GetGlossary(FileManager.GetBytesFromFile(pdfFile));}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets a glossary. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="pdfFile">	The pdf file. </param>
		///
		/// <returns>	The glossary. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static string GetGlossary(byte[] pdfFile) {
			IDocClass doc = new IDocClass();
			doc.OpenMem(pdfFile,"");
			StringBuilder sb = new StringBuilder();
			while(true) {
				TToken token = doc.GetToken();
				if( token == null )break;
				try {
					sb.Append(token.Text+" ");
				}
				catch{break;}
			}
			return sb.ToString();
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets a numeric glossary. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="pdfFile">	The pdf file. </param>
		///
		/// <returns>	The numeric glossary. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static ArrayList GetNumericGlossary(string pdfFile) {return GetNumericGlossary(FileManager.GetBytesFromFile(pdfFile));}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets a numeric glossary. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="pdfFile">	The pdf file. </param>
		///
		/// <returns>	The numeric glossary. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static ArrayList GetNumericGlossary(byte[] pdfFile) {
			ArrayList arl = new ArrayList();
			IDocClass doc = new IDocClass();
			doc.OpenMem(pdfFile,"");
			while(true) {
				TToken token = doc.GetToken();
				if( token == null )break;
				string number = "";
				for(int i=0;i<token.Text.Length;i++) {
					try{number += int.Parse(token.Text.Substring(i,1)).ToString();}
					catch{break;}
				}
				try{if(number.Length>3) arl.Add(int.Parse(number));}
				catch{}
			}
			return arl;
		}
	}
}